#include <io.h>		// access()
#include <string.h>

#include <windows.h>

#include "lib.h"

#include "patch.h"
#include "admadd.h"
#include "admpipe.h"

#include "patchsrv.h"
#include "pkglist.h"
#include "pkgdesc.h"

//
// This protocol assumes the client on the other end of the pipe has rejected
// all attempts to add an invalid package (minimal checks for dups and
// non-existent files).
//

void
AdminAddPkg::handle(uint8* msg, int32 len)
{
	if (pipe->isLoggedOn())
	{
		uint8* name, *zip;
//		String name, zip;
		uint32 version;
		uint8* pver;
		PackageDescription *pkg, *probe;
		PackageList* list;

		name = msg + 2;			// skip <A><name len>

		pver = name + msg[1];	// point to version
		version = (uint32)(
			(pver[3] & 0xFF) |
			((pver[2]<<8)&0xFF00) |
			((pver[1]<<16)&0xFF0000) |
			((pver[0]<<24)&0xFF000000));

		name[name[-1]] = '\0';

		zip = pver + 4 + 1;
		zip[zip[-1]] = '\0';		// ASSUMES 1 byte avail after msg!

		if (name[-1] == 0 || zip[-1] == 0)
		{
			pipe->sendError(APE_INVALID_ADD);
			return;
		}
		
		pkg = new PackageDescription((char*)name, version, (char*)zip);
		if (!pkg || !pkg->getName() || !pkg->getZipName())
		{
			pipe->sendError(APE_MEMORY_ERROR);
			return;
		}

		list = PatchServer::This->lockPackageList();
		if (!list)
		{
			delete pkg;
			PatchServer::This->unlockPackageList();
			pipe->sendError(APE_MEMORY_ERROR);
			return;
		}

		probe = list->getItem(0);
		while (probe)
		{
			if (probe->getName() &&
//				(0 == strcmpi(probe->getName(), pkg->getName()) ||
//				 0 == strcmpi(probe->getZipName(), pkg->getZipName())))
				(probe->getName() == pkg->getName()) ||
				(probe->getZipName() == pkg->getZipName()))
				break;

			probe = probe->getNext();
		}
		
		if (probe || -1 == _waccess(pkg->getZipName(), 0))
		{
			delete pkg;
			PatchServer::This->unlockPackageList();
			pipe->sendError(APE_INVALID_ADD);
			return;
		}

		list->addItem(pkg);
		list->save();

		PatchServer::This->unlockPackageList();

		pipe->msgStart();
		pipe->msgAdd('S');
		pipe->msgEnd();
	}
	else
		pipe->sendError(APE_UNKNOWN_REQUEST);
}
